package com.fulihui.systemcore.service;

import com.fulihui.systemcore.api.PhoneRegLocService;
import com.fulihui.systemcore.dto.PhoneRegLocDTO;
import com.fulihui.systemcore.integration.baidu.PhoneRegLocBaiduApi;
import com.fulihui.systemcore.repository.PhoneRegLocRepository;
import com.fulihui.systemcore.request.phoneregloc.PhoneRegLocMobilesRequest;
import org.apache.dubbo.config.annotation.Service;
import org.near.servicesupport.result.ResultBuilder;
import org.near.servicesupport.result.TSingleResult;
import org.near.servicesupport.util.ServiceAssert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

import static org.near.servicesupport.error.Errors.Commons.REQUEST_PARAMETER_ERROR;

/**
 * @author Willard.Hu on 2016/11/29 0029.
 */
@Service(version = "1.0.0")
public class PhoneRegLocServiceImpl implements PhoneRegLocService {
    final Logger          log = LoggerFactory.getLogger(getClass());
    @Autowired
    PhoneRegLocRepository phoneRegLocRepository;
    @Autowired
    PhoneRegLocBaiduApi   phoneRegLocBaiduApi;
    /**
     * 线程池
     */
    ExecutorService       executorService;

    @PostConstruct
    void init() {
        executorService = Executors.newFixedThreadPool(10);
    }

    @PreDestroy
    void destroy() {
        if (executorService != null && !executorService.isShutdown()) {
            executorService.shutdown();
        }
    }

    @Override
    public TSingleResult<Map<String, PhoneRegLocDTO>> queryByMobiles(PhoneRegLocMobilesRequest request) {
        List<String> mobiles = request.getMobileNos();
        Map<String, PhoneRegLocDTO> rs;
        if (CollectionUtils.isEmpty(mobiles)) {
            rs = Collections.emptyMap();
        } else {
            ServiceAssert.isTrue(request.getMobileNos().size() <= 20, REQUEST_PARAMETER_ERROR);
            List<Integer> prefixs = mobiles.stream().map(it -> {
                return Integer.parseInt(it.substring(0, 7));
            }).collect(Collectors.toList());
            Map<Integer, PhoneRegLocDTO> data = phoneRegLocRepository.queryByPrefixs(prefixs);
            rs = new HashMap<>();
            mobiles.forEach(it -> {
                int prefix = Integer.parseInt(it.substring(0, 7));
                // 缓存本次远程调用
                PhoneRegLocDTO phoneRegLocDTO = null;
                if (data.isEmpty() || (phoneRegLocDTO = data.get(prefix)) == null) {
                    try {
                        phoneRegLocDTO = phoneRegLocBaiduApi.query(prefix);
                        // 远程调用给缓冲时间，百度api 1秒最多只能调用100次
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException ignore) {
                        }

                        if (phoneRegLocDTO != null) {
                            final PhoneRegLocDTO create = phoneRegLocDTO;
                            executorService.execute(() -> phoneRegLocRepository.create(create));
                        }
                    } catch (Exception e) {
                        log.error(e.getMessage(), e);
                    }
                }
                if (phoneRegLocDTO != null) {
                    rs.put(it, phoneRegLocDTO);
                }
            });
        }
        return ResultBuilder.succTSingle(rs);
    }
}
